<?php
/**
 * Created by ephp
 * User: 22071
 * Date: 2019/6/14
 * Email: <zhendongdong@foxmail.com>
 */

namespace paper\exception;

use Exception;
use paper\App;
use paper\constraint\ExceptionsHandler;
use paper\http\Response;

class Handler implements ExceptionsHandler
{
    private $app;

    public function __construct(App $app)
    {
        $this->app = $app;
    }

    /**
     * @param $errno
     * @param $errstr
     * @param $errfile
     * @param $errline
     * @return Response
     */
    public function errorHandler($errno, $errstr, $errfile, $errline)
    {
        return self::handler($errstr, $errfile, $errline, null, "");
    }

    /**
     * @param \Exception $exception
     * @return Response
     */
    public function render($exception)
    {
        $subMessage = '';
        if ($exception instanceof ResponseException) {
            return $exception->getResponse();
        } else if ($exception instanceof DbException) {
            $subMessage = str_replace("\r\n", "<br>", $exception->getSql());
            $subMessage = str_replace(" ", "&nbsp;", $subMessage);
            $subMessage = str_replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;", $subMessage);
        }
        //处理异常
        return $this->handler(
            $exception->getMessage(),
            $exception->getFile(),
            $exception->getLine(),
            $exception->getTrace(),
            $subMessage
        );
    }


    /**
     * @param $message
     * @param $file
     * @param $line
     * @param null $trace
     * @param string $subMessage
     * @param bool $debug
     * @return Response
     */
    private function handler($message, $file, $line, $trace = null, $subMessage = '')
    {
        $debug = config('app', 'debug');
        return Response::create(function () use ($message, $file, $line, $trace, $subMessage, $debug) {
            if ($debug) {
                $file_content = htmlspecialchars(file_get_contents($file), ENT_QUOTES);
                $file_content = str_replace("\r\n", "\n", $file_content);
                $file_content = str_replace(" ", "&nbsp;", $file_content);
                $lines        = explode("\n", $file_content);
                if (count($lines) <= 20) {
                    $start = 0;
                } else {
                    $start = ($line - 10) ?: 0;
                }
                $nl = array_slice($lines, $start, 20);
                include(PAPERPHP . '/library/tpl/exception.php');
            }
        }, $debug ? 500 : 404, 'exception');
    }

    /**
     * @param Exception $exception
     */
    public function report($exception)
    {
        $this->app->log->error($exception->getMessage());
    }
}